package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceCode;
import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.CategoryMapper;
import cn.tedu.csmall.product.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.CategoryUpdateDTO;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.vo.CategoryListItemVO;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.service.ICategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Slf4j
public class CategoryServiceImpl implements ICategoryService {


    @Autowired
    CategoryMapper mapper;

    @Transactional
    @Override
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        //根据对象的name属性查询类别表是否存在同名的类别
        int num= mapper.countByName(categoryAddNewDTO.getName());
        //如果存在，抛出异常，异常代码：ERR_CONFLICT，类别信息：添加失败，类别【"+category.getName()+"】已存在！
        if(num>0){
            String message="添加失败，类别【"+categoryAddNewDTO.getName()+"】已存在！";
            log.debug("添加失败，类别【{}】已存在",categoryAddNewDTO.getName());
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        CategoryStandardVO queryResult = null;
        // 声明局部变量depth，默认值为1
        // 取出参数中的parentId
        // 判断parentId是否不为0
        // 是：调用Mapper对象的【根据id查询详情】，使用parentId作为参数，执行查询
        // -- 判断查询结果是否不为null
        // -- 是：局部变量depth=父级depth+1
        // -- 否：父级类别不存在，抛出异常（NOT_FOUND）
        int depth=1;
        Long parentId=categoryAddNewDTO.getParentId();
        if(parentId!=0){
            queryResult=mapper.getCategoryStandardVO(parentId);
            if(queryResult!=null){
                depth+=queryResult.getDepth();
                log.debug(categoryAddNewDTO.getName()+"的菜单深度为：{}",depth);
            }else {
                String message=categoryAddNewDTO.getName()+"的父级类别不存在！";
                log.debug("{}的父级类别不存在！",categoryAddNewDTO.getName());
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
            }
        }


        //如果不存在，创建类别对象，把VO类的属性复制到类别对象
        Category category=new Category();
        BeanUtils.copyProperties(categoryAddNewDTO,category);
        category.setSort(2);
        category.setIsParent(0);
        category.setDepth(depth);
        log.info("准备添加品牌：{}",category);

        int row=mapper.insert(category);
        log.debug("添加成功！");
        if(row!=1){
            String message="添加失败，系统繁忙，请稍后重试！";
            log.debug("添加类别【{}】失败!",category);
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }

        // 判断parentId是否不为0
        // 是：判断父级类别的isParent是否为0
        // -- 是：创建新的Category对象，封装：parentId，isParent(1)
        // -- -- 调用Mapper对象的【更新】方法，执行修改数据，并获取返回值
        // -- -- 判断返回值是否不为1
        // -- -- -- 是：抛出异常（ERR_UPDATE）

        if(parentId!=0){
            if(queryResult.getIsParent()==0){
                Category updateCategory=new Category();
                updateCategory.setId(parentId);
                updateCategory.setIsParent(1);
                int rows=mapper.updateById(updateCategory);
                if(rows!=1){
                    String message="添加失败，系统异常，请稍后重试！";
                    log.debug("更新父类parentId和isParent失败！");
                    throw new ServiceException(ServiceCode.ERR_UPDATE,message);
                }
            }
        }
    }


    @Override
    public void deleteById(Long id) {
        // 调用Mapper对象的【根据id查询详情】查询数据，是当前尝试删除的数据
        CategoryStandardVO categoryStandardVO = mapper.getCategoryStandardVO(id);
        // 判断查询结果是否为null
        if (categoryStandardVO == null) {
            // 是：数据不存在，抛出异常（ERR_NOT_FOUND）
            String message = "删除失败，数据不存在！";
            log.debug("删除失败，数据不存在！");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 检查当前尝试删除的类别是否存在子级类别：判断以上查询结果的isParent是否为1
        // 是：当前尝试删除的类别“是父级类别”（包含子级），抛出异常（ERR_CONFLICT）
        if (categoryStandardVO.getIsParent() == 1) {
            String message = "删除失败，id为" + categoryStandardVO.getId() + "的数据存在子级类别！";
            log.debug("删除失败，id为{}的数据存在子级类别！", categoryStandardVO.getId());
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 调用Mapper对象的【根据id删除】执行删除，并获取返回值
        int row = mapper.deleteById(id);
        log.debug("删除成功！");
        // 判断返回值是否不为1
        if (row != 1) {
            // 是：抛出异常（ERR_DELETE）
            String message = "删除失败，系统繁忙，请稍后重试！";
            log.debug("删除失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }

        // ======如果这是父级类别中的最后一个子级，则将父级的isParent改为0

        // 从当前尝试删除的类别对象中取出parentId
        Long parentId = categoryStandardVO.getParentId();
        // 判断当前类别是否不为1级类别，即parentId不为0
        if (parentId != 0) {
            // 调用Mapper对象的countByParentId(parentId)进行统计
            int num = mapper.countByParentId(parentId);
            // 判断统计结果是否为0
            if (num == 0) {
                // 创建新的Category对象，用于更新父级，此Category对象中需要封装：id（parentId），isParent（0）
                Category updateCategory = new Category();
                updateCategory.setId(parentId);
                updateCategory.setIsParent(0);
                // 调用Mapper对象的【更新】功能，执行修改数据，并获取返回值
                int rows = mapper.updateById(updateCategory);
                // 判断返回值是否不为1
                // 是：抛出异常（ERR_UPDATE）
                if (rows != 1) {
                    String message = "系统繁忙，请稍后重试！";
                    log.debug("父类的isParent修改失败！");
                    throw new ServiceException(ServiceCode.ERR_UPDATE, message);
                }
            }
        }
    }

    /**
     * 根据id启用类别
     * @param id
     */
    @Override
    public void setEnable(Long id) {
        //根据id获取类别的VO对象
        CategoryStandardVO queryResult=mapper.getCategoryStandardVO(id);
        //判断对象是否为null，是null抛出异常
        if(queryResult==null){
            String message="启用失败，此类别不存在！";
            log.debug("启用失败，此类别不存在！");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        log.debug("被启用的类别存在！");

        //获取该对象的enable字段值
        int enable = queryResult.getEnable();
        //判断是否已经是启用状态
        if(enable==1){
            //已经是启用状态，抛出异常
            String message="启用失败，此类别已经是启用状态！";
            log.debug("启用失败，此类别已经是启用状态！");
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        log.debug("准备启用类别！");
        //创建category实体类对象
        Category category=new Category();
        //设置被修改数据的id
        category.setId(id);
        //设置被修改数据的enable值
        category.setEnable(1);
        int rows=mapper.updateById(category);
        //判断被修改数据的行数
        if(rows!=1){
            //不等于1，抛出异常
            String message="启用失败，系统繁忙，请稍后重试！";
            log.debug("启用失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        log.debug("id为{}的类别启用成功！",id);
    }

    /**
     * 根据id禁用类别
     * @param id
     */
    @Override
    public void setDisable(Long id) {
        //获取被禁用类别的VO对象
        CategoryStandardVO queryResult=mapper.getCategoryStandardVO(id);
        //判断被禁用类别是否存在
        if(queryResult==null){
            //如果不存在，抛出not_fount异常
            String message="禁用失败，此类别不存在！";
            log.debug("禁用失败，此类别不存在！");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        log.debug("该类别存在！");

        //如果存在，再判断该类别的enable值
        int enable = queryResult.getEnable();
        //如果当前为禁用状态
        if(enable==0){
            //抛出异常
            String message="启用失败，此类别已经是禁用状态！";
            log.debug("启用失败，此类别已经是禁用状态！");
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        log.debug("该类别是禁用状态！");

        //创建类别对象
        Category category=new Category();
        //设置id值和enable值
        category.setId(id);
        category.setEnable(0);
        //调用mapper接口的updateById方法，获取受影响的行数
        int rows = mapper.updateById(category);
        //如果受影响行数不等于1
        if(rows!=1){
            //不等于1，抛出异常
            String message="禁用失败，系统繁忙，请稍后重试！";
            log.debug("禁用失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        log.debug("id为【{}】的类别禁用成功！",id);
    }

    /**
     * 根据id显示类别
     * @param id
     */
    @Override
    public void setDisplay(Long id) {
        //获取被修改类别的VO对象
        CategoryStandardVO queryResult= mapper.getCategoryStandardVO(id);
        //如果对象为空，抛出异常
        if(queryResult==null){
            String message="设置显示失败，此类别不存在！";
            log.debug("设置显示失败，此类别不存在！");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        log.debug("类别存在！");
        //如果存在，获取当前类别的显示状态
        int isDisplay = queryResult.getIsDisplay();
        //如果已经是显示状态，抛出异常
        if(isDisplay==1){
            String message="设置显示失败，当前已经是显示状态！";
            log.debug("设置显示失败，当前已经是显示状态！");
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        log.debug("当前类别为隐藏状态");

        //创建类别对象
        Category category=new Category();
        //设置被修改类别的id和isDisplay值
        category.setId(id);
        category.setIsDisplay(1);
        //调用mapper接口的updateById方法
        int rows = mapper.updateById(category);
        //如果受影响行数不等于1，抛出异常
        if(rows!=1){
            String message="设置显示失败，系统繁忙，请稍后重试！";
            log.debug("设置显示失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        log.debug("id为【{}】的类别设置为显示状态！",id);
    }

    /**
     * 根据id隐藏类别
     * @param id
     */
    @Override
    public void setHidden(Long id) {
        //获取被修改类别的VO对象
        CategoryStandardVO queryResult= mapper.getCategoryStandardVO(id);
        //如果对象为空，抛出异常
        if(queryResult==null){
            String message="设置显示失败，此类别不存在！";
            log.debug("设置显示失败，此类别不存在！");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        log.debug("类别存在！");
        //如果存在，获取当前类别的显示状态
        int isDisplay = queryResult.getIsDisplay();
        //如果已经是显示状态，抛出异常
        if(isDisplay==0){
            String message="设置隐藏失败，当前已经是隐藏状态！";
            log.debug("设置隐藏失败，当前已经是隐藏状态！");
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        log.debug("当前类别为显示状态");

        //创建类别对象
        Category category=new Category();
        //设置被修改类别的id和isDisplay值
        category.setId(id);
        category.setIsDisplay(0);
        //调用mapper接口的updateById方法
        int rows = mapper.updateById(category);
        //如果受影响行数不等于1，抛出异常
        if(rows!=1){
            String message="设置隐藏失败，系统繁忙，请稍后重试！";
            log.debug("设置显示失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        log.debug("id为【{}】的类别设置为隐藏状态！",id);
    }

    /**
     * 根据id修改类别基本资料
     * @param categoryUpdateDTO
     */
    @Override
    public void updateById(Long id,CategoryUpdateDTO categoryUpdateDTO) {
        //根据id查询类别表数据数量
        log.debug("根据id修改品牌资料！");
        String categoryName=categoryUpdateDTO.getName();
        CategoryStandardVO queryResult = mapper.getCategoryStandardVO(id);
        //如果查询结果不等于1，抛出异常
        if(queryResult==null){
            String message="修改失败，类别不存在！";
            log.debug("修改失败，类别不存在！",categoryName);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        log.debug("类别存在！");

        //创建类别对象，把DTO对象复制到类别对象中
        Category category=new Category();
        BeanUtils.copyProperties(categoryUpdateDTO,category);
        category.setId(id);
        //调用mapper接口的updateById方法
        int rows = mapper.updateById(category);
        if(rows!=1){
            String message="修改失败，系统繁忙，请稍后重试！";
            log.debug("修改失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        log.debug("类别【{}】修改成功！",categoryName);
    }


    /**
     * 根据id获取类别表的详细信息
     * @param id 根据id获取类别表的详细信息
     * @return
     */
    @Override
    public CategoryStandardVO getCategoryStandardVO(Long id) {
        log.debug("开始处理【根据id查询类别详情】的业务");
        CategoryStandardVO category= mapper.getCategoryStandardVO(id);
        if(category==null){
            String message="查询类别详情失败，尝试访问的数据不存在！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        return category;
    }

    /**
     * 根据父级类别获取类别列表
     * @param parentId
     * @return
     */
    @Override
    public List<CategoryListItemVO> list(Long parentId) {
        log.debug("开始根据父级类别id获取类别列表！");
        return mapper.list(parentId);
    }


}
